<?php

namespace app\service\payment\gateway;

use app\constant\CommonConstant;
use app\exception\BusinessException;
use app\helpers\UtilHelper;
use app\libs\DianDianPaySDK\action\PaymentApi;
use app\libs\DianDianPaySDK\builder\DianDianPaymentBuilder;
use app\libs\PaypalSDK\action\PurchasePaypal;
use app\libs\PaypalSDK\builder\PurchaseBuilder;
use app\libs\PaypalSDK\builder\RepurchasePaypal;
use app\libs\WeChatSDK\Action\PushMessage;
use app\model\Notify;
use app\model\Orders;
use app\model\ShopsPayment;
use think\helper\Arr;
use think\Request;

class DianDianService implements PaymentInterface
{

    /**
     * @param Orders $order
     * @param Request $request
     * @return array
     * @throws \Exception
     * @desc 创建订单
     */
    public function placeOrder(Orders $order, Request $request): array
    {
        $card = $request->param("card",[]);
        $order->card_number = Arr::get($card,"cardNumber");
        $order->payment_token = $card;
        $order->save();
        return $this->createPaymentByCard($order,$request);

    }


    public function confirmPayment()
    {
        // TODO: Implement confirmPayment() method.
    }

    /**
     * @param Orders $order
     * @param Request $request
     * @return array
     * @throws \Exception
     * @desc 加购
     */
    public function repurchase(Orders $order, Request $request): array
    {
        return $this->createPaymentByCard($order,$request);
    }

    private function createPaymentByCard(Orders $order, Request $request)
    {
        $this->checkCardNumberLimit($order->card_number);//卡次数限制
        $diandianReplaceId = env('DIANDIAN_PAY_REPLACE_ID');
        try {
            //第一次支付
            $response = $this->callDianDianAPI($order, $request);
            $data = Arr::get($response,'data',[]);
            $result_code = Arr::get($data,'result.result_code','');
            $this->savePayResult($order,$data);
            if(empty($data) || $result_code == 'FAILED') throw new \Exception("fist pay fail");
        }catch (\Exception $e){
            dump($e);//二抛
            $cardType = UtilHelper::getCardType($order->card_number);
            if(in_array($cardType,['V','M'])){
                dump("点点支付第一次报错信息: " .$e->getMessage());
                $order->pay_id = $diandianReplaceId;//修改pay_id
                $order->save();
                $response2 = $this->callDianDianAPI($order,$request,false);
                $data = Arr::get($response2,'data',[]);
                $this->savePayResult($order,$data);
            }else{
                throw new BusinessException(CommonConstant::PAYMENT_EXCEPTION);
            }
        }
        $result_code = Arr::get($data,'result.result_code','');
        if($result_code == 'FAILED') throw new BusinessException(Arr::get($data,'result.result_message'));
        $redirectUrl = Arr::get($data,'next_action.redirect_url','');
        if($redirectUrl)return compact('redirectUrl');
        return ['pay_result'=>$data];
    }

    private function checkCardNumberLimit(mixed $card_number)
    {
        if(env("APP_ENV") != "pro") return true;
        $count = Orders::query()->where('order_status',Orders::ORDER_STATUS_FAIL)
            ->where('order_type',Orders::ORDER_DRAFT)
            ->where('pay_method',ShopsPayment::PAY_METHOD_DIANDIAN)
            ->where('card_number',$card_number)
            ->count('id');
        if($count >= 2) throw new BusinessException($card_number." fail gt 2 count");
    }

    //下单
    private function callDianDianAPI(Orders $order,Request $request,$isFirst=true)
    {
        $sdk = $order->payment->config;
        $app_user = Arr::get($sdk,'merchant_no');
        $count = $isFirst ? "first" : "second";
        $card = $order->payment_token;
        $merchantOrderId = sprintf("%s%s",$order->name,time());
        $builder = new DianDianPaymentBuilder($order,$request);
        $body = $builder
            ->setMerchantId($app_user)
            ->setCard($card)
            ->setMerchantOrderId($merchantOrderId)// 设置商户订单号
            ->toArray();

        $client = new PaymentApi($order->payment);
        $type = $order->is_repurchase ? Notify::TYPE_REPURCHASE : Notify::TYPE_PLACE_ORDER;
        try {
            $response = $client->create_payment($body);
            Notify::saveParams($order->id,['params'=>$body,'response'=>$response,'apiRequest'=>$count],$type,$order->pay_method);
            return  $response;
        }catch (\Exception $e){
            Notify::saveParams($order->id,['params'=>$body,'error'=>$e->getMessage(),'apiRequest'=>$count],$type,$order->pay_method);
            throw new \Exception($e->getMessage());
        }

    }

    //保存结果
    private function savePayResult(Orders $order,array $data=[])
    {
        if(empty($data)) return false;
        $isSave = false;
        if($tradeNo=Arr::get($data, 'id','')){
            $order->trade_no = $tradeNo;
            $isSave = true;
        }
        if($orderNo=Arr::get($data, "merchant_order_id",'')){
            $order->order_no = $orderNo;
            $isSave = true;
        }
        if($pay_status=Arr::get($data, 'result.result_status', '')){
            $order->pay_status = $pay_status ;
            $isSave = true;
        }
        if($isSave) $order->save();
        return true;
    }



}